package org.example.lanchain.service.impl;

import org.example.lanchain.bean.User;
import org.example.lanchain.dto.LoginRequest;
import org.example.lanchain.dto.LoginResponse;
import org.example.lanchain.dto.RegisterRequest;
import org.example.lanchain.mapper.UserMapper;
import org.example.lanchain.service.UserService;
import org.example.lanchain.tools.JwtUtil;
import org.example.lanchain.tools.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private PasswordUtil passwordUtil;
    
    // 内存中存储活跃token（生产环境建议使用Redis）
    private final ConcurrentHashMap<String, Long> activeTokens = new ConcurrentHashMap<>();
    
    // 最大登录失败次数
    private static final int MAX_LOGIN_FAIL_COUNT = 5;
    
    // 账户锁定时间（分钟）
    private static final int LOCK_DURATION_MINUTES = 30;
    
    @Override
    @Transactional
    public LoginResponse login(LoginRequest request) {
        try {
            // 查找用户
            User user = userMapper.findByUsername(request.getUsername());
            if (user == null) {
                return LoginResponse.failure("用户名或密码错误");
            }
            
            // 检查账户状态
            if (!"active".equals(user.getStatus())) {
                if ("banned".equals(user.getStatus())) {
                    // 检查是否已过锁定时间
                    if (user.getLockTime() != null) {
                        LocalDateTime unlockTime = user.getLockTime().plusMinutes(LOCK_DURATION_MINUTES);
                        if (LocalDateTime.now().isBefore(unlockTime)) {
                            return LoginResponse.failure("账户已被锁定，请稍后再试");
                        } else {
                            // 解锁账户
                            userMapper.unlockAccount(user.getId());
                            user.setStatus("active");
                            user.setLoginFailCount(0);
                            user.setLockTime(null);
                        }
                    }
                } else {
                    return LoginResponse.failure("账户状态异常，请联系管理员");
                }
            }
            
            // 验证密码
            if (!passwordUtil.matches(request.getPassword(), user.getPassword())) {
                // 增加登录失败次数
                int failCount = user.getLoginFailCount() == null ? 1 : user.getLoginFailCount() + 1;
                userMapper.updateLoginFailCount(user.getId(), failCount);
                
                if (failCount >= MAX_LOGIN_FAIL_COUNT) {
                    // 锁定账户
                    userMapper.lockAccount(user.getId(), LocalDateTime.now());
                    return LoginResponse.failure("登录失败次数过多，账户已被锁定30分钟");
                }
                
                return LoginResponse.failure("用户名或密码错误");
            }
            
            // 登录成功，重置失败次数
            userMapper.updateLoginFailCount(user.getId(), 0);
            
            // 更新最后登录时间
            LocalDateTime now = LocalDateTime.now();
            userMapper.updateLastLoginTime(user.getId(), now);
            user.setLastLoginTime(now);
            
            // 生成JWT令牌
            String token = jwtUtil.generateToken(user.getUsername(), user.getId(), request.getRememberMe());
            
            // 存储活跃token
            activeTokens.put(token, user.getId());
            
            // 构建用户信息
            LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
            userInfo.setId(user.getId());
            userInfo.setUsername(user.getUsername());
            userInfo.setEmail(user.getEmail());
            userInfo.setRole(user.getRole());
            userInfo.setStatus(user.getStatus());
            userInfo.setLastLoginTime(user.getLastLoginTime());
            
            // 计算过期时间
            LocalDateTime expireTime = request.getRememberMe() ? 
                now.plusSeconds(jwtUtil.getExpirationDateFromToken(token).getTime() / 1000) :
                now.plusSeconds(jwtUtil.getExpirationDateFromToken(token).getTime() / 1000);
            
            return LoginResponse.success(token, userInfo, expireTime);
            
        } catch (Exception e) {
            return LoginResponse.failure("登录失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public User register(RegisterRequest request) {
        // 验证密码确认
        if (!request.getPassword().equals(request.getConfirmPassword())) {
            throw new RuntimeException("两次输入的密码不一致");
        }
        
        // 验证密码强度
        if (!passwordUtil.isPasswordStrong(request.getPassword())) {
            throw new RuntimeException("密码强度不够，请包含字母和数字");
        }
        
        // 检查用户是否已存在
        if (isUserExists(request.getUsername(), request.getEmail())) {
            throw new RuntimeException("用户名或邮箱已存在");
        }
        
        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPassword(passwordUtil.encodePassword(request.getPassword()));
        user.setRole("user"); // 默认普通用户
        user.setStatus("active");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setLoginFailCount(0);
        user.setRememberMe(false);
        
        // 保存用户
        userMapper.insert(user);
        
        return user;
    }
    
    @Override
    public void logout(String token) {
        if (token != null) {
            activeTokens.remove(token);
        }
    }
    
    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }
    
    @Override
    public User findByEmail(String email) {
        return userMapper.findByEmail(email);
    }
    
    @Override
    public boolean isUserExists(String username, String email) {
        User existingUser = userMapper.findByUsername(username);
        if (existingUser != null) {
            return true;
        }
        
        existingUser = userMapper.findByEmail(email);
        return existingUser != null;
    }
    
    @Override
    @Transactional
    public User updateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        return user;
    }
    
    @Override
    @Transactional
    public boolean deleteUser(Long userId) {
        return userMapper.deleteById(userId) > 0;
    }
    
    @Override
    @Transactional
    public boolean resetPassword(String email, String newPassword) {
        User user = userMapper.findByEmail(email);
        if (user == null) {
            return false;
        }
        
        user.setPassword(passwordUtil.encodePassword(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        return true;
    }
    
    @Override
    public boolean validateToken(String token) {
        if (token == null || !activeTokens.containsKey(token)) {
            return false;
        }
        return jwtUtil.validateToken(token);
    }
    
    @Override
    public User getUserByToken(String token) {
        if (!validateToken(token)) {
            return null;
        }
        
        Long userId = activeTokens.get(token);
        if (userId == null) {
            return null;
        }
        
        return userMapper.selectById(userId);
    }
} 